We first read in two data sets called “philly” representing several different values having to due with crimes that have occurred in the Philadelphia area since 2015. “Philly” has 15520 observations and 18 total variables.
philly <- na.omit(st_read("https://pengdsci.github.io/STA553VIZ/w08/PhillyShootings.geojson"))
phillyNeighbor <- st_read("https://pengdsci.github.io/STA553VIZ/w08/Neighborhoods_Philadelphia.geojson")
head(philly)
Simple feature collection with 6 features and 21 fields
Geometry type: POINT
Dimension: XY
Bounding box: xmin: -75.10962 ymin: 40.01166 xmax: -75.08552 ymax: 40.01489
Geodetic CRS: WGS 84
objectid year dc_key code date_ time race sex age
1 12728033 2016 201615054780.0 400 2016-06-06 20:00:00 12:15:00 B M 19
2 12728034 2016 201615117555.0 300 2016-12-03 19:00:00 05:43:00 B M 38
3 12728035 2018 201815093657.0 400 2018-10-13 20:00:00 21:02:00 B M 31
4 12728036 2020 202015094989.0 400 2020-12-01 19:00:00 17:12:00 B M 23
5 12728037 2018 201824100255.0 400 2018-11-08 19:00:00 04:29:00 B M 27
6 12728038 2019 201924106228.0 400 2019-10-27 20:00:00 04:10:00 W M 22
wound officer_involved offender_injured offender_deceased
1 Hand N N N
2 Chest N N N
3 Multiple N N N
4 Hand N N N
5 Arm N N N
6 Multiple N N N
location latino point_x point_y dist inside outside
1 4600 BLOCK Frankford Ave 0 -75.08552 40.01489 15 0 1
2 4600 BLOCK Frankford Ave 0 -75.08552 40.01489 15 0 1
3 4600 BLOCK Frankford Ave 0 -75.08552 40.01489 15 0 1
4 4600 BLOCK FRANKFORD AVE 0 -75.08552 40.01489 15 0 1
5 900 BLOCK E Hunting Park Ave 0 -75.10962 40.01167 24 0 1
6 900 BLOCK E HUNTING PARK AVE 1 -75.10962 40.01167 24 0 1
fatal geometry
1 0 POINT (-75.08552 40.01489)
2 0 POINT (-75.08552 40.01489)
3 1 POINT (-75.08552 40.01489)
4 0 POINT (-75.08552 40.01489)
5 0 POINT (-75.10962 40.01167)
6 0 POINT (-75.10962 40.01167)
head(phillyNeighbor)
Simple feature collection with 6 features and 8 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -75.28027 ymin: 39.96271 xmax: -75.01684 ymax: 40.09464
Geodetic CRS: WGS 84
name listname mapname shape_leng
1 PENNYPACK_PARK Pennypack Park Pennypack Park 87084.29
2 OVERBROOK Overbrook Overbrook 57004.92
3 GERMANTOWN_SOUTHWEST Germantown, Southwest Southwest Germantown 14880.74
4 EAST_PARKSIDE East Parkside East Parkside 10885.78
5 GERMANY_HILL Germany Hill Germany Hill 13041.94
6 MOUNT_AIRY_EAST Mount Airy, East East Mount Airy 28845.55
shape_area cartodb_id created_at updated_at
1 60140756 9 2013-03-19 13:41:50 2013-03-19 13:41:50
2 76924995 138 2013-03-19 13:41:50 2013-03-19 13:41:50
3 14418666 59 2013-03-19 13:41:50 2013-03-19 13:41:50
4 4231000 129 2013-03-19 13:41:50 2013-03-19 13:41:50
5 6949968 49 2013-03-19 13:41:50 2013-03-19 13:41:50
6 43152470 6 2013-03-19 13:41:50 2013-03-19 13:41:50
geometry
1 MULTIPOLYGON (((-75.05645 4...
2 MULTIPOLYGON (((-75.22719 3...
3 MULTIPOLYGON (((-75.16208 4...
4 MULTIPOLYGON (((-75.19931 3...
5 MULTIPOLYGON (((-75.22722 4...
6 MULTIPOLYGON (((-75.18088 4...
Now, we can create a leaflet map looking at fatal versus non-fatal crimes that occured in Philadelphia in the year 2023 by using the “color” function once again. The color is dependent on whether or not a crime was labeled as “Fatal” or “Nonfatal”. So, each category will have a specific color, representing the type of crime (fatal vs. nonfatal) that occurred at the time. The map is similar to the previous maps above in which each circle point represents a specific crime. Hovering over a point will give the “Neighborhood”, “Date”, “Race”, and “Sex”, “Age”, and “Street” for that specific crime.
library(leaflet)
library(sf)
library(htmltools)
library(dplyr)
## Create sf object
philly_sf <- st_as_sf(philly, coords = c("point_x", "point_y"), crs = 4326)
# Define color palette for fatal and non-fatal crimes
pal <- leaflet::colorFactor(
palette = c("red", "gold"),
domain = c("Fatal", "Non-Fatal")
)
fatal_color <- "red"
non_fatal_color <- "gold"
map <- leaflet(philly) %>%
addTiles() %>%
addCircleMarkers(
~point_x, ~point_y,
color = ifelse(philly$fatal == 1, fatal_color, non_fatal_color),
radius = 5,
popup = ~paste("Object ID: ", objectid,
"Year: ", year,
"Race: ", race,
"Sex: ", sex,
"Age: ", age,
"Wound: ", wound,
"Location: ", location),
labelOptions = labelOptions(
direction = "auto"
)
) %>%
addLegend(
position = "bottomright",
colors = c(fatal_color, non_fatal_color),
labels = c("Fatal", "Non-Fatal"),
title = "Crime Type"
) %>%
addScaleBar() %>%
addControl(
html = "<h4>Philadelphia Crime Locations (2015-2024)</h4>",
position = "topright"
)%>%
setView(lng = -75.1527, lat = 39.9707, zoom = 11) %>%
addProviderTiles(providers$Esri.WorldGrayCanvas) %>%
addPolygons(data = phillyNeighbor,
color = 'skyblue',
weight = 1) %>%
addCircleMarkers(data = philly_sf,
radius = 5,
color = ~pal(fatal),
stroke = FALSE,
fillOpacity = 0.5,
clusterOptions = markerClusterOptions(maxClusterRadius = 40)) %>%
# Adding images to the map
addMarkers(lng = -75.1652, lat = 39.9526, popup = '<img src="https://pengdsci.github.io/STA553VIZ/w08/PhillyCityHall.jpg" width="200" height="200">') %>%
# HTML style for the map title
addControl(HTML('<div class="leaflet-control.map-title">Philadelphia Crime Locations (2015-2024)</div>'), position = "topright") %>%
addLayersControl(baseGroups = c('Dark', 'DarkLabel', 'Esri'),
overlayGroups = c("Crime Data"),
options = layersControlOptions(collapsed = TRUE))
# Display the map
map